using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using Yoozoo.Gameplay.City;

namespace Yoozoo.Gameplay.CityEditor
{
    public class CityFeatureConfigWindow : EditorWindow
    {
        private const string configPath = "Assets/Arts/Tools/Config/cityFeatureConfig.json";
        private static CityFeatureConfig _featureConfig;
        private static SerializedObject serializedObject;

        private static CityFeatureConfigWindow instance;
        public List<RoomFeature> RoomFeatures;
        public List<HudFeature> HudFeatures;
        private void OnEnable()
        {
            instance = this;
            UpdateConfig();
        }

        [MenuItem("GTATools/GamePlay/InnerCity/内城功能配置窗口")]
        private static void ShowWindow()
        {
            var window = GetWindow<CityFeatureConfigWindow>();
            window.minSize = new Vector2(200, 400);
            window.titleContent = new GUIContent("内城功能配置");
            window.Show();
        }

        public static GUIContent roomHeaderText = EditorGUIUtility.TrTextContent("房间列表", "所有内城房间ID与脚本文件匹配");
        private SerializedProperty m_roomListProp;
        private ReorderableList m_roomRenderList;
        
        public static GUIContent hudHeaderText = EditorGUIUtility.TrTextContent("HUD(只增不减)", "所有内城hud类型");
        private SerializedProperty m_hudListProp;
        private ReorderableList m_hudRenderList;
        
        private static void UpdateConfig()
        {
            var jsonText = AssetDatabase.LoadAssetAtPath<TextAsset>(configPath);
            _featureConfig = JsonUtility.FromJson<CityFeatureConfig>(jsonText.text);
            instance.HudFeatures = _featureConfig.HudFeatures;
            instance.RoomFeatures = _featureConfig.RoomFeatures;
            serializedObject = new SerializedObject(instance);
            instance.RefreshConfig();
        }

        private void RefreshConfig()
        {
            m_roomListProp = serializedObject.FindProperty("RoomFeatures");
            m_roomRenderList = new ReorderableList(serializedObject, m_roomListProp, true, true,true, true);
            DrawRoomListLayout(m_roomRenderList, m_roomListProp);
            
            m_hudListProp = serializedObject.FindProperty("HudFeatures");
            m_hudRenderList = new ReorderableList(serializedObject, m_hudListProp, true, true,true, true);
            DrawHudListLayout(m_hudRenderList, m_hudListProp);
        }

        private void CheckRoomLuaFile()
        {
            string luaDicPath = Application.dataPath + "/../Lua/modules/city/room/";
            //TODO  创建不存在的Lua文件
            foreach (var roomFeature in RoomFeatures)
            {
                
            }
            
        }

        private void CheckHudFile()
        {
            // Lua文件
            string luaDicPath = Application.dataPath + "/../Lua/modules/city/hud/";
            foreach (var hudFeature in HudFeatures)
            {
                
            }
            
            string fConfigPath =  Application.dataPath + "/../Lua/modules/city/config/CityFeatureEnum.lua";
            if (File.Exists(fConfigPath))
            {
                File.Delete(fConfigPath);
                AssetDatabase.Refresh();
            }
            FileStream fs = new FileStream(fConfigPath, FileMode.Create, FileAccess.Write);
            using (StreamWriter writer = new StreamWriter(fs))
            {
                writer.WriteLine("--代码自动生成，不能手动修改！！！");
                writer.WriteLine();
                writer.WriteLine("E_HUD_Behavior_Type = {");

                for (int i = 0; i < HudFeatures.Count; i++)
                {
                    HudFeature hudFeature = HudFeatures[i];
                    writer.WriteLine($"    {hudFeature.EnumName} = {hudFeature.HudID},");
                }
                writer.WriteLine("}");
                writer.Flush();
                writer.Close();
                fs.Close();
            }
            
            // C#文件
            string cEnumConfig = Application.dataPath + "/Scripts/Gameplay/City/Config/CityHudEnum.cs";
            if (File.Exists(cEnumConfig))
            {
                File.Delete(cEnumConfig);
                AssetDatabase.Refresh();
            }
            FileStream fs1 = new FileStream(cEnumConfig, FileMode.Create, FileAccess.Write);
            using (StreamWriter writer = new StreamWriter(fs1))
            {
                writer.WriteLine("//代码自动生成，不能手动修改！！！");
                writer.WriteLine();
                writer.WriteLine("namespace Yoozoo.Gameplay.City");
                writer.WriteLine("{");
                writer.WriteLine("    public enum CityHudEnum");
                writer.WriteLine("    {");

                for (int i = 0; i < HudFeatures.Count; i++)
                {
                    HudFeature hudFeature = HudFeatures[i];
                    writer.WriteLine($"        {hudFeature.EnumName} = {hudFeature.HudID},");
                }
                writer.WriteLine("    }");
                writer.WriteLine("}");
                writer.Flush();
                writer.Close();
                fs1.Close();
            }
            
            AssetDatabase.Refresh();
        }
        
        private void Save2Json()
        {
            CityFeatureConfig featureConfig = new CityFeatureConfig();
            featureConfig.RoomFeatures = RoomFeatures;
            featureConfig.HudFeatures = HudFeatures;

            var jsonText = JsonUtility.ToJson(featureConfig,true);

            if (File.Exists(configPath))
            {
                File.Delete(configPath);
                AssetDatabase.Refresh();
            }
            FileStream fs = new FileStream(configPath, FileMode.Create, FileAccess.Write);
            using (StreamWriter writer = new StreamWriter(fs))
            {
                writer.Write(jsonText);
                writer.Flush();
                writer.Close();
                fs.Close();
            }
            string luapath = Application.dataPath + "/../Lua/modules/city/config/CityFeatureConfig.lua";
            if (File.Exists(luapath))
            {
                File.Delete(luapath);
                AssetDatabase.Refresh();
            }
            FileStream luafs = new FileStream(luapath, FileMode.Create, FileAccess.Write);
            var luatxt = JsonToLua.ConvertLua(jsonText);
            using (StreamWriter writer = new StreamWriter(luafs))
            { writer.Write(luatxt);
                writer.Flush();
                writer.Close();
                luafs.Close();
            }

            AssetDatabase.Refresh();
        }

        private Vector2 scrollPos;
        private void OnGUI()
        {
            if (serializedObject!=null)
            {
                serializedObject.Update();

                scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
                
                GUILayout.Space(10);
                
                if (m_roomRenderList!=null)
                {
                    m_roomRenderList.DoLayoutList();
                }
                
                GUILayout.Space(20);

                if (m_hudRenderList!=null)
                {
                    m_hudRenderList.DoLayoutList();
                }

                EditorGUILayout.EndScrollView();
                
                GUILayout.Space(40);
                
                if (GUILayout.Button("保存",GUILayout.Height(30)))
                {
                    CheckRoomLuaFile();
                    CheckHudFile();
                    Save2Json();
                    UpdateConfig();
                    
                    RoomDataEditor.UpdateCityConfig();
                    EditorUtility.DisplayDialog("", "导出配置成功 ^_^", "ok");
                }
                
                serializedObject.ApplyModifiedProperties();
            }
          
        }
        
        private void DrawRoomListLayout(ReorderableList list, SerializedProperty prop)
        {
            list.elementHeight = EditorGUIUtility.singleLineHeight * 1.25f + 1;
            
            list.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
            {
                EditorGUIUtility.labelWidth = 60;
                var element = prop.GetArrayElementAtIndex(index);
                rect.y += 2;
                SerializedProperty idProperty = element.FindPropertyRelative("RoomID");
                Rect idRect = new Rect(rect.x, rect.y, 150, EditorGUIUtility.singleLineHeight);
                idProperty.intValue = EditorGUI.IntField(idRect, "房间ID", idProperty.intValue);
                
                rect.x += 2 + idRect.width + 10;
                SerializedProperty luaProperty = element.FindPropertyRelative("RoomLuaFileName");
                Rect luaRect = new Rect(rect.x , rect.y , 180, EditorGUIUtility.singleLineHeight);
                luaProperty.stringValue = EditorGUI.TextField(luaRect, "Lua文件名", luaProperty.stringValue);
                
                rect.x += 2 + luaRect.width + 10;
                SerializedProperty nameProperty = element.FindPropertyRelative("Name");
                Rect nameRect = new Rect(rect.x, rect.y, 160, EditorGUIUtility.singleLineHeight);
                nameProperty.stringValue = EditorGUI.TextField(nameRect, "房间名", nameProperty.stringValue);
            };
            
            list.drawHeaderCallback = (Rect rect) =>
            {
                EditorGUI.LabelField(rect, roomHeaderText);
            };
            
            list.onCanRemoveCallback = li => { return li.count > 0; };
        }

        private Dictionary<string, GameObject> hudPrefabCaches = new Dictionary<string, GameObject>();

        private void DrawHudListLayout(ReorderableList list, SerializedProperty prop)
        {
            list.elementHeight = EditorGUIUtility.singleLineHeight * 1.25f * 4f + 10;
            
            list.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
            {
                EditorGUIUtility.labelWidth = 80;
                var element = prop.GetArrayElementAtIndex(index);
                rect.y += 2;
                rect.x += 10;
                
                SerializedProperty enumProperty = element.FindPropertyRelative("EnumName");
                Rect enumRect = new Rect(rect.x, rect.y, 200, EditorGUIUtility.singleLineHeight);
                enumProperty.stringValue = EditorGUI.TextField(enumRect, "枚举名", enumProperty.stringValue);
                
                SerializedProperty idProperty = element.FindPropertyRelative("HudID");
                Rect idRect = new Rect(rect.x + 10 + enumRect.width, rect.y, 150, EditorGUIUtility.singleLineHeight);
                idProperty.intValue = EditorGUI.IntField(idRect, "枚举ID", idProperty.intValue);

                rect.y += idRect.height + 5;
                SerializedProperty luaProperty = element.FindPropertyRelative("HudLuaFileName");
                Rect luaRect = new Rect(rect.x , rect.y , 240, EditorGUIUtility.singleLineHeight);
                luaProperty.stringValue = EditorGUI.TextField(luaRect, "Lua文件名", luaProperty.stringValue);

                rect.y += luaRect.height + 5;
                SerializedProperty pathProperty = element.FindPropertyRelative("HudPrefabPath");

                if (!string.IsNullOrEmpty(pathProperty.stringValue) && !hudPrefabCaches.ContainsKey(pathProperty.stringValue))
                {
                    hudPrefabCaches[pathProperty.stringValue] = AssetDatabase.LoadAssetAtPath<GameObject>(pathProperty.stringValue);
                }
                
                Rect prefabRect = new Rect(rect.x, rect.y, 220, EditorGUIUtility.singleLineHeight);
                GameObject p = null;
                if (!string.IsNullOrEmpty(pathProperty.stringValue))
                {
                    hudPrefabCaches.TryGetValue(pathProperty.stringValue, out p);
                }
                var op = EditorGUI.ObjectField(prefabRect, "预设体",p, typeof(GameObject),false);
                if (op!=null)
                {
                    pathProperty.stringValue = AssetDatabase.GetAssetPath(op);
                    hudPrefabCaches[pathProperty.stringValue] = op as GameObject;
                }
                else
                {
                    if (hudPrefabCaches.ContainsKey(pathProperty.stringValue))
                    {
                        hudPrefabCaches.Remove(pathProperty.stringValue);
                    }
                    pathProperty.stringValue = "";
                }

                rect.y += prefabRect.height + 5;
                Rect pathRect = new Rect(rect.x, rect.y, 480, EditorGUIUtility.singleLineHeight);
                GUI.enabled = false;
                pathProperty.stringValue = EditorGUI.TextField(pathRect, "预设体路径", pathProperty.stringValue);
                GUI.enabled = true;
            };
            
            list.drawHeaderCallback = (Rect rect) =>
            {
                EditorGUI.LabelField(rect, hudHeaderText);
            };
            
            list.onCanRemoveCallback = li => { return false; };
        }
    }
}